package com.hotchpotch.okHttp;

import android.os.Environment;
import android.util.Log;

import com.hotchpotch.base.MyApplication;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2017/7/6 0006.
 */

public class MyOkHttp {
    private static MyOkHttp myOkHttp = new MyOkHttp();
    private OkHttpClient client;//创建okHttpClient对象
    private OnOkHttpResultListener onOkHttpResultListener;

    public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
    public static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

    private MyOkHttp() {
        initOkHttpClient();
    }

    public static MyOkHttp getInstence() {
        return myOkHttp;
    }

    private void initOkHttpClient() {
        File sdcache = MyApplication.getContext().getExternalCacheDir();
        int cacheSize = 10 * 1024 * 1024;
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
        client = builder.build();
    }

    /**
     * 外部调用的get
     *
     * @param url
     * @param onOkHttpResultListener
     */
    public void doGet(String url, OnOkHttpResultListener onOkHttpResultListener) {
        this.onOkHttpResultListener = onOkHttpResultListener;
        getAsynHttp(url);
    }

    /**
     * 外部调用的post方法
     *
     * @param url
     * @param formBody
     * @param onOkHttpResultListener
     */
    public void doPost(String url, RequestBody formBody, OnOkHttpResultListener onOkHttpResultListener) {
        this.onOkHttpResultListener = onOkHttpResultListener;
        postAsynHttp(url, formBody);
    }

    /**
     * 外部调用的上传方法
     *
     * @param url
     * @param mediaType
     * @param fileUrl
     * @param onOkHttpResultListener
     */
    public void doUpload(String url, MediaType mediaType, String fileUrl, OnOkHttpResultListener onOkHttpResultListener) {
        this.onOkHttpResultListener = onOkHttpResultListener;
        postAsynFile(url, mediaType, fileUrl);
    }

    /**
     * 外部调用的下载方法
     *
     * @param url
     * @param fileName
     * @param onOkHttpResultListener
     */
    public void doDownLoad(String url, final String fileName, OnOkHttpResultListener onOkHttpResultListener) {
        this.onOkHttpResultListener = onOkHttpResultListener;
        downAsynFile(url, fileName);
    }

    /**
     * 异步get
     */
    private void getAsynHttp(String url) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        //可以省略，默认是GET请求
        requestBuilder.method("GET", null);
        execute(requestBuilder);
    }

    /**
     * 异步post
     * RequestBody formBody = new FormBody.Builder().add("size", "10").build();(formBody的写法)
     */
    private void postAsynHttp(String url, RequestBody formBody) {
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(formBody);
//        Request request = builder.build();
        execute(builder);
    }

    /**
     * 异步上传文件
     */
    private void postAsynFile(String url, MediaType mediaType, String fileUrl) {
        File file = new File(fileUrl);
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(RequestBody.create(mediaType, file));
        execute(builder);
    }

    /**
     * 异步下载文件
     *
     * @param url
     * @param fileName 格式：/xxx.xxx
     */
    private void downAsynFile(String url, final String fileName) {
//        String url = "http://img.my.csdn.net/uploads/201603/26/1458988468_5804.jpg";
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                try {
                    fileOutputStream = new FileOutputStream(new File(Environment.getDownloadCacheDirectory().getPath().toString() + fileName));
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();
                } catch (IOException e) {
                    Log.i("okHttp", "IOException");
                    e.printStackTrace();
                }
                Log.d("okHttp", "文件下载成功");
            }
        });
    }

    /**
     * 执行请求
     *
     * @param builder
     */
    private void execute(Request.Builder builder) {
        Call call = client.newCall(builder.build());
        call.enqueue(callback);//加入调度队列
    }

    /**
     * 请求回调
     */
    private Callback callback = new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i("okHttp", "onFailure");
            e.printStackTrace();
            if (onOkHttpResultListener != null) {
                onOkHttpResultListener.onFailure();
            }
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //从response从获取服务器返回的数据，转成字符串处理
            String str = new String(response.body().bytes(), "utf-8");
            if (onOkHttpResultListener != null) {
                onOkHttpResultListener.onResponse(str);
            }
        }
    };

    /**
     * 监听
     */
    public interface OnOkHttpResultListener {
        void onFailure();

        void onResponse(String result);
    }
}
